/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.knowledge.facts;

import com.knowledge.facts.paths.AttackHillPathFact;
import com.knowledge.facts.paths.ExplorePathFact;
import com.knowledge.facts.paths.GotoEnemyPathFact;
import com.knowledge.facts.paths.GotoFoodPathFact;
import com.knowledge.facts.paths.GotoHivePathFact;
import com.knowledge.facts.paths.PathFact;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeMap;

/**
 *
 * @author keithballantyne
 */
@SuppressWarnings("unchecked")
public class FactRepository {
    private static FactRepository instance = null;
        
    // TreeMap is log(n) search by class name
    // HashSet is Constant Time search for element.
    TreeMap<Class,HashSet<Fact> > repo = new TreeMap<Class,HashSet<Fact> >(new ClassComparator());
    
    protected FactRepository() {
        repo.put(EnemyAntFact.class,new HashSet<Fact>());
        repo.put(FriendlyAntFact.class, new HashSet<Fact>());
        repo.put(EnemyHillFact.class, new HashSet<Fact>());
        repo.put(FriendlyHillFact.class, new HashSet<Fact>());
        repo.put(UnexploredFact.class, new HashSet<Fact>());
        repo.put(FoodFact.class, new HashSet<Fact>());
        repo.put(IntendedLocationFact.class, new HashSet<Fact>());
        repo.put(GotoFoodPathFact.class, new HashSet<Fact>());
        repo.put(AttackHillPathFact.class, new HashSet<Fact>());
        repo.put(ExplorePathFact.class, new HashSet<Fact>());
        repo.put(GotoEnemyPathFact.class, new HashSet<Fact>());
        repo.put(GotoHivePathFact.class, new HashSet<Fact>());
    }
        
    public static FactRepository getInstance() {
        if(instance == null) {
            instance = new FactRepository();
        }
        return instance;
    }
    
    public void printSize() {
        System.err.println("Repo size: "+repo.size());
    }
    
    
    public boolean hasFactClass(Class c) {
        return !repo.get(c).isEmpty();
    }
    
    public boolean hasFactInstance(Fact f) {
        Set<Fact> facts = repo.get(f.getClass());
        
        return repo.get(f.getClass()).contains(f);
    }

    public void removeAllInstances(Class c) {
        repo.get(c).clear();
    }
    
    public boolean addInstance(Fact f) {
        return repo.get(f.getClass()).add(f);
    }
    
    public boolean removeInstance(Fact f) {
        return repo.get(f.getClass()).remove(f);
    }

    public Set<Fact> getInstances(Class c) {
        return repo.get(c);
    }

    public Set<FriendlyAntFact> getFriendlyAnts() {
        Set<FriendlyAntFact> retval = new HashSet(repo.get(FriendlyAntFact.class));
        
        return retval;
    }

    public Set<Fact> getPathFacts() {
        HashSet<Fact> pathFacts = new HashSet<Fact>();
        pathFacts.addAll(getInstances(GotoFoodPathFact.class));
        pathFacts.addAll(getInstances(ExplorePathFact.class));
        pathFacts.addAll(getInstances(AttackHillPathFact.class));
        pathFacts.addAll(getInstances(GotoEnemyPathFact.class));
        pathFacts.addAll(getInstances(GotoHivePathFact.class));
        
        return pathFacts;
    }

    public void removePaths(Set<Fact> removeFacts) {
        
//        System.err.println("Removing facts: "+removeFacts.size());
        repo.get(GotoFoodPathFact.class).removeAll(removeFacts);
        repo.get(AttackHillPathFact.class).removeAll(removeFacts);
        repo.get(ExplorePathFact.class).removeAll(removeFacts);
        repo.get(GotoEnemyPathFact.class).removeAll(removeFacts);
        repo.get(GotoHivePathFact.class).removeAll(removeFacts);
    }
}
